package com.usian.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.usian.mapper.WmMaterialMapper;
import com.usian.mapper.WmNewsMapper;
import com.usian.mapper.WmNewsMaterialMapper;
import com.usian.mapper.WmUserMapper;
import com.usian.model.admin.dtos.NewsAuthDto;
import com.usian.model.common.dtos.PageResponseResult;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.media.dtos.WmNewsDto;
import com.usian.model.media.dtos.WmNewsPageReqDto;
import com.usian.model.media.pojos.WmMaterial;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmNewsMaterial;
import com.usian.model.media.pojos.WmUser;
import com.usian.service.WmNewsService;
import com.usian.utils.threadlocal.WmThreadLocalUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {


    @Value("${fileServerUrl}")
    private String fileServerUrl;

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmUserMapper wmUserMapper;

    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Autowired
    private WmNewsMapper wmNewsMapper;


    @Override
    public ResponseResult findList(WmNewsPageReqDto dto) {

        if(dto==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        dto.checkParam();

        Page page =new Page(dto.getPage(),dto.getSize());

        QueryWrapper<WmNews> queryWrapper =new QueryWrapper<>();
        //
        if(dto.getStatus()!=null){
            queryWrapper.lambda().eq(WmNews::getStatus,dto.getStatus());
        }
        if(StringUtils.isNotBlank(dto.getKeyword())){
            queryWrapper.lambda().like(WmNews::getTitle,dto.getKeyword());
        }
        if(dto.getChannelId()!=null){
            queryWrapper.lambda().eq(WmNews::getChannelId,dto.getChannelId());
        }
        if(dto.getBeginPubDate()!=null && dto.getEndPubDate()!=null){
            queryWrapper.lambda().between(WmNews::getPublishTime,dto.getBeginPubDate(),dto.getEndPubDate());
        }
        WmUser wmUser = WmThreadLocalUtils.getUser();
        if(wmUser!=null){
            queryWrapper.lambda().eq(WmNews::getUserId,wmUser.getId());
        }
        queryWrapper.lambda().orderByDesc(WmNews::getCreatedTime);

        IPage result =this.page(page,queryWrapper);

        ResponseResult responseResult =new PageResponseResult(dto.getPage(),dto.getSize(),(int)result.getTotal());
        responseResult.setData(result.getRecords());
        responseResult.setHost(fileServerUrl);
        return responseResult;
    }

    @Override
    public ResponseResult saveNews(WmNewsDto dto, Short isSubmit) {

        //1:校验参数
        if(dto==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2：完成对象copy 保存wmnews
        WmNews wmNews =new WmNews();
        BeanUtils.copyProperties(dto,wmNews);
        if(dto.getType()==-1){
            //保存文章封面是自动模式
            wmNews.setType(null);
        }
        //获取参数中的封面图片 提取出来
        //[http://192.168.58.138/group1/M00/24/xssdsdsds.jpg] ==> group1/M00/24/xssdsdsds.jpg
        if(dto.getImages()!=null && dto.getImages().size()!=0){
            String imageStr = dto.getImages().toString();
            String replaceImageStr = imageStr.replace("[", "").replace("]", "").replace(fileServerUrl, "").replace(" ", "");
            wmNews.setImages(replaceImageStr);
        }
        //保存主表wmnews
        this.saveNews(wmNews,isSubmit);


        //2.提取内容中的图片
        String content = dto.getContent();
        //json串转成javalist集合
        List<Map> imageList = JSON.parseArray(content, Map.class);
        //判断解析图片放到一个新的集合中  images 内容中解析出来的图片地址
        List<String> images = this.ectractUrlInfo(imageList);


        //3:对比内容提取出来的图片去甄别 是否是素材库的图片
        if(isSubmit == 1 && images.size() != 0){
            ResponseResult responseResult = this.saveRelativeInfo(images, wmNews.getId());
            if(responseResult.getCode()!=0){
                return responseResult;
            }

        }

        //4:设置封面
        if(isSubmit==1){
            ResponseResult responseResult = this.saveRelativeInfoForCover(dto, images, wmNews);
            if(responseResult.getCode()!=0){
                return responseResult;
            }
        }

        //5：保存成功后使用kafka发送文章id
        System.out.println("文章id"+wmNews.getId());
        kafkaTemplate.send("autoScanNews",JSON.toJSONString(wmNews.getId()));

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    private ResponseResult saveRelativeInfoForCover(WmNewsDto dto, List<String> materials, WmNews wmNews) {
        List<String> images = dto.getImages();
        //自动匹配封面
        if (dto.getType()==-1) {
            //内容中的图片数量小于等于2  设置为单图
            if (materials.size() > 0 && materials.size() <= 2) {
                wmNews.setType((short)1);
                images = materials.stream().limit(1).collect(Collectors.toList());
            } else if (materials.size() > 2) {
                //如果内容中的图片大于2 则设置为多图
                wmNews.setType((short)3);
                images = materials.stream().limit(3).collect(Collectors.toList());
            } else {
                //内容中没有图片，则是无图
                wmNews.setType((short)0);
            }
            //修改文章信息
            if (images != null && images.size() > 0) {
                wmNews.setImages(images.toString().replace("[", "")
                        .replace("]", "").replace(fileServerUrl, "")
                        .replace(" ", ""));

            }
            updateById(wmNews);
        }
        //保存封面图片与素材的关系
        if (images != null && images.size() > 0) {
            ResponseResult responseResult = saveRelativeInfo(images, wmNews.getId());
            if (responseResult != null) {
                return responseResult;
            }
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    private ResponseResult  saveRelativeInfo(List<String> images,Integer newsId){

        //先数据库 in 范围查询 查到库中存在的素材 list

        LambdaQueryWrapper<WmMaterial> lambdaQueryWrapper =new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(WmMaterial::getUrl,images);
        WmUser wmUser = WmThreadLocalUtils.getUser();
        if(wmUser!=null){
            lambdaQueryWrapper.eq(WmMaterial::getUserId,wmUser.getId());
        }
        List<WmMaterial> materialListDB = wmMaterialMapper.selectList(lambdaQueryWrapper);

        //list 转换成map

        List<String> materialIds =new ArrayList<>();

        if(materialListDB.size()>0){
            Map<String, Integer> map = materialListDB.stream().collect(
                    Collectors.toMap(WmMaterial::getUrl, WmMaterial::getId));

            //甄别
            for(String imgurl :images){

                if(map.get(imgurl).equals("null")){

                }else{

                    materialIds.add(map.get(imgurl).toString());
                }
            }

            //批量保存关系表
            wmNewsMaterialMapper.saveRelationsByContent(materialIds,newsId,1);
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

    }

    private List<String> ectractUrlInfo(List<Map> imageList){
        List<String> images = new ArrayList<>();

        for(Map map : imageList){
            //比较 去获取 type==image 取出来  value  图片地址
            if(map.get("type").equals("image")){
                String imageUrl =(String) map.get("value");
                //图片格式转换
                imageUrl = imageUrl.replace(fileServerUrl,"");
                images.add(imageUrl);
            }
        }
        return images;
    }

    private void saveNews(WmNews wmNews,Short isSubmit){
        wmNews.setStatus(isSubmit);
        WmUser wmUser = WmThreadLocalUtils.getUser();
        if(wmUser!=null){
            wmNews.setUserId(wmUser.getId());
        }
        wmNews.setEnable((short)0); //1上架 0下架
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());

        //保存  修改
        if(wmNews.getId()==null){
            this.save(wmNews);
        }else{
            //删除关系表
            wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId,wmNews.getId()));
            this.updateById(wmNews);
        }
    }


    @Override
    public ResponseResult findById(Integer id) {
        if(id==null){
            ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        WmNews wmNews = this.getById(id);
        if(wmNews==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        ResponseResult responseResult = ResponseResult.okResult(wmNews);
        responseResult.setHost(fileServerUrl);

        return responseResult;
    }

    @Override
    public ResponseResult delNews(Integer id){
        if(id==null){
            ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        WmNews wmNews = this.getById(id);
        if(wmNews==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");
        }

        //发布 9 and enable 1 上架
        if(wmNews.getStatus()==9 && wmNews.getEnable()== 1){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不能删除");
        }

        wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId,id));

        this.removeById(id);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult downOrUp(WmNewsDto dto){
        if(dto==null){
            ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //根据文章id查询文章对象
        WmNews wmNews = this.getById(dto.getId());
        if(wmNews==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");
        }

        //判断 stauts=9 才能上下架
        if(wmNews.getStatus()==9){
            //enable 只能传0 1
            if(wmNews.getEnable()==0 ||wmNews.getEnable()==1){
                this.update(Wrappers.<WmNews>lambdaUpdate().set(WmNews::getEnable,dto.getEnable()).eq(WmNews::getId,dto.getId()));

                //上下架新增使用kafka发送文章消息，消费者接受更新ap_article_config is_down 数据
                Map<String,Object> map =new HashMap<>();
                map.put("enable",wmNews.getEnable());
                map.put("articleId",wmNews.getArticleId());
                kafkaTemplate.send("shangxiajia",JSON.toJSONString(map));

            }else{
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"上下架状态码不正确");
            }
        }else{
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH,"文章未发布不能执行上下架操作");
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

    }

    @Override
    public WmNews findByNewId(Integer id) {
        if(id==null){
            return null;
        }
        return this.getById(id);
    }

    @Override
    public boolean updateNews(WmNews wmNews) {

        boolean b = this.updateById(wmNews);
        return b;
    }

    @Override
    public WmUser findByUserId(Integer id) {
        if(id==null){
            return null;
        }
        return wmUserMapper.selectById(id);
    }

    @Override
    public List<Integer> findWmnews() {

        List<WmNews> wmNewsList = this.list(Wrappers.<WmNews>lambdaQuery().eq(WmNews::getStatus, 8).lt(WmNews::getPublishTime, new Date()));

        List<Integer> list = wmNewsList.stream().map(WmNews::getId).collect(Collectors.toList());

        return list;
    }

    @Override
    public PageResponseResult findListRengong(NewsAuthDto dto) {
        dto.checkParam();

        //重新赋值计算page值  （page-1）*size
        dto.setPage((dto.getPage()-1)*dto.getSize());

        //查询详情
        List<WmNews> wmNewsList = wmNewsMapper.findNewsList(dto);

        //查询总条数
        int count = wmNewsMapper.findNewsListCount(dto);

        PageResponseResult responseResult =new PageResponseResult(dto.getPage(),dto.getSize(),count);
        responseResult.setData(wmNewsList);

        return responseResult;
    }

    @Override
    public WmNews findDetail(Integer id){
        if(id==null){
            return null;
        }

        WmNews wmNews = this.getById(id);

        if(wmNews.getUserId()!=null){
            WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
            if(wmUser!=null){
                wmNews.setAuthorName(wmUser.getName());
            }
        }
        return wmNews;
    }

    @Override
    public ResponseResult auth(NewsAuthDto dto,int type) {

        if(dto==null ||dto.getId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        WmNews wmNews = this.getById(dto.getId());
        if(wmNews==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        if(type==0){
            //不通过
            this.update(Wrappers.<WmNews>lambdaUpdate()
                    .set(WmNews::getStatus,2)
                    .set(WmNews::getReason,dto.getMsg())
                    .eq(WmNews::getId,dto.getId()));

        }else if(type==1){
            //通过
            this.update(Wrappers.<WmNews>lambdaUpdate()
                    .set(WmNews::getStatus,4)
                    .eq(WmNews::getId,dto.getId()));
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
